/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/xoskit.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#ifndef __XOS_STL_HELPER_INIT_TERM_OBJ_H__
#define __XOS_STL_HELPER_INIT_TERM_OBJ_H__

namespace xos_common
{
	class i_common;
}

namespace xos_stl
{

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 
	// 这类方法的函数指针模板 
	// 

	template< class T >
	using f_item_operation = int(*)(T*&);

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 
	// release interface 
	// 

	template< class T >
	int release_interface( T *& pObj )
	{
		int ret = 0;
		if( pObj )
		{
			pObj->release();
			pObj = 0;
		}
		return ret;
	}

	template< class T >
	int release_ref( T *& pObj )
	{
		int ret = 0;
		if( pObj )
		{
			pObj->release_ref();
			pObj = 0;
		}
		return ret;
	}

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 
	// group 
	// 
	template< class T >
	int init_group( T *& pGroup, xos_common::i_common * pCommon )
	{
		int ret = 0;
		pGroup = new T( pCommon );
		if( !pGroup )
		{
			ret = 1;
		}
		return ret;
	}

	template< class T >
	int term_group( T *& pGroup )
	{
		int ret = 0;
		if( pGroup )
		{
			pGroup->put_back_to_pool();
			delete pGroup;
			pGroup = 0;
		}
		return ret;
	}

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 
	// list 
	// 
	template< class T >
	int init_list( T *& pList )
	{
		int ret = 0;
		pList = new T;
		if( !pList )
		{
			ret = 1;
		}
		return ret;
	}

	template< class T >
	int term_list( T *& pList )
	{
		int ret = 0;
		if( pList )
		{
			pList->put_back_to_pool();
			delete pList;
			pList = 0;
		}
		return ret;
	}

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 
	// map 
	// 
	template< class T >
	int init_map( T *& pMap )
	{
		int ret = 0;
		pMap = new T;
		if( !pMap )
		{
			ret = 1;
		}
		return ret;
	}

	template< class T >
	int term_map( T *& pMap )
	{
		int ret = 0;
		if( pMap )
		{
			pMap->put_back_to_pool();
			delete pMap;
			pMap = 0;
		}
		return ret;
	}

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 
    // pool item 
    // 
    template< class T >
    int init_pool_item( T *& pItem )
    {
        int ret = 0;
        pItem = T::get_item_from_pool();
        if( pItem )
        {
            ret = pItem->init();
        }
        else
        {
            ret = 1;
        }
        return ret;
    }

    template< class T >
    int term_pool_item( T *& pItem )
    {
        int ret = 0;
        if( pItem )
        {
            pItem->term();
            pItem->put_back_to_pool();
            pItem = 0;
        }
        return ret;
    }

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 
	// item 
	// 
	template< class T >
	int init_item( T *& pItem )
	{
		int ret = 0;
		pItem = new T;
		if( pItem )
		{
			ret = pItem->init();
		}
		else
		{
			ret = 1;
		}
		return ret;
	}

	template< class T >
	int term_item( T *& pItem )
	{
		int ret = 0;
		if( pItem )
		{
			pItem->term();
			delete pItem;
			pItem = 0;
		}
		return ret;
	}

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 
	// object 
	// 
	template< class T >
	int init_obj( T *& pObj )
	{
		int ret = 0;
		pObj = new T;
		if( !pObj )
		{
			ret = 1;
		}
		return ret;
	}

	template< class T >
	int term_obj( T *& pObj )
	{
		int ret = 0;
		if( pObj )
		{
			delete pObj;
			pObj = 0;
		}
		return ret;
	}

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 
	// array 
	// 
	template< class T >
	int init_array( T *& pObj, int nNum )
	{
		int ret = 0;
		pObj = new T[nNum];
		if( !pObj )
		{
			ret = 1;
		}
		return ret;
	}

	template< class T >
	int term_array( T *& pObj )
	{
		int ret = 0;
		if( pObj )
		{
			delete [] pObj;
			pObj = 0;
		}
		return ret;
	}

	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 
	// module init
	// 

	template< class OBJ, class INTERFACE >
	int static_init_module( xos_container::i_container* pContainer, INTERFACE** ppv, xos_container::i_container*& container_ptr, OBJ*& mgr_ptr )
	{
		int ret = 0;

		typedef typename OBJ::T XOS_OBJ;

		XOS_OBJ* pObj = 0;

		if( (0 == ret) && mgr_ptr )
		{
			ret = 1;
		}

		if( (0 == ret) && !ppv )
		{
			ret = 1;
		}

		if( 0 == ret )
		{
			container_ptr = pContainer;
		}

		if( 0 == ret )
		{
			pObj = new XOS_OBJ;
			if( !pObj )
			{
				ret = 1;
			}
		}

		if( 0 == ret )
		{
			mgr_ptr = pObj;
		}

		if( 0 == ret )
		{
			ret = pObj->init();
		}

		if( 0 == ret )
		{
			*ppv = pObj;
			pObj = 0;
		}

		xos_stl::release_interface( pObj );

		if( 0 != ret )
		{
			mgr_ptr = 0;
		}

		return ret;
	}

} // xos_stl

#endif // __XOS_STL_HELPER_INIT_TERM_OBJ_H__
